package com.acme.multithreadinglab.factorizer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class Factorizer  implements Computable<Integer, Integer[]>{
	static private int count = 0;
	private int cachedInput=0;
	private Map<Integer, Integer> cachedResult;
	private int cachedResultInt;
	
	public Integer[] compute(Integer x) {
		int number = x;
		List<Integer> factors = new ArrayList<Integer>();
		final List<Integer> primes = generatePrimes(number);
		
		int curPrimeIndex = 0;
		while (number > 1) {
			if ((number % primes.get(curPrimeIndex)) == 0) {
				number /= primes.get(curPrimeIndex);
				factors.add(primes.get(curPrimeIndex));
			} else {
				curPrimeIndex++;
			}
		}
		count++;
		cachedInput = x;
		cachedResultInt = factors.hashCode();
		return factors.toArray(new Integer[1]);
	}

	public int getCount() {
		return count;
	}
	
	public int getCachedInput() {
		return cachedInput;
	}
	
	public int getCachedResult() {
		return cachedResultInt;
	}
	
	private static List<Integer> generatePrimes(final int max) {
		List<Integer> primes = new ArrayList<Integer>();
		boolean[] isPrime = new boolean[max + 1];
	
		Arrays.fill(isPrime, true);
		isPrime[1] = false;
		for (int i = 2; i * i <= max; i++) {
			if (isPrime[i]) {
				for (int j = i * i; j <= max; j += i) {
					isPrime[j] = false;
				}
			}
		}
	
		for (int i = 2; i <= max; i++) {
			if (isPrime[i]) {
				primes.add(i);
			}
		}
		return primes;
	}
}